'''
此模块用于处理身份证号相关的问题。

1.验证身份证号是否有效。
2.获取身份证号码中的有效信息。
3.粗略对身份证号格式化。
'''

import re

id_pattern = re.compile(r"^([0-9]{2})([0-9]{4})([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{1})([0-9xX]{1})$")
mutil_code = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
map_code = [1,0,'X',9,8,7,6,5,4,3,2]

def id_format(idcard):
    '''对数据进行格式化。包含转换大小写，截取长度。
    '''
    idcard = idcard.strip().upper()
    return idcard[:18]

def check_code(idcard):
    sum = 0
    for i,c in enumerate(idcard[:-1]):
        sum += int(c) * mutil_code[i]
    mod = sum % 11
    return str(map_code[mod])

def id_verify(idcard):
    '''验证身份证号是否为有效的格式。简单初级验证。
    '''
    idcard = idcard.strip().upper()
    idinfo = id_pattern.match(idcard)
    if idinfo:
        check = check_code(idcard)
        if idcard[-1]!= check:
            return False
        return True
    else:
        return False
    
def id_verify_full(idcard):
    '''验证身份证号是否为有效的格式。包含数据校验。
    '''
    id_data = {}
    idcard = idcard.strip().upper()
    idinfo = id_pattern.match(idcard)
    if idinfo:
        #通过算法计算第18位，验证身份证号
        check = check_code(idcard)
        if idcard[-1]!= check:
            raise ValueError('id:{} 校验码出错！'.format(idcard))
        id_data['province_code'] = int(idinfo[1])
        id_data['county_code'] = int(idinfo[2])
        id_data['year'] = int(idinfo[3])
        id_data['month'] = int(idinfo[4])
        id_data['day'] = int(idinfo[5])
        id_data['region'] = int(idinfo[6])
        id_data['gender'] = int(idinfo[7])
        id_data['vercode'] = idinfo[8]
        if id_data['year'] < 1900 or id_data['year'] > 2100:
            raise ValueError('id:{} 年份[{}]错误！'.format(idcard,id_data['year']))
        if id_data['month'] <= 0 or id_data['month'] > 12:
            raise ValueError('id:{} 月份[{}]错误！'.format(idcard,id_data['month']))
        if id_data['day'] <= 0 or id_data['day'] > 31:
            raise ValueError('id:{} 生日[{}]错误！'.format(idcard,id_data['day']))
    else:
        raise ValueError('id:{} 不满足身份证号的基本格式或长度要求！'.format(idcard))
    return id_data